home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PsL Monthly 1993 December
/
PSL Monthly Shareware CD-ROM (December 1993).iso
/
prgmming
/
dos
/
pascal
/
gsdbloo.exe
/
GS_DBL.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1992-02-28
|
12KB
|
360 lines
{------------------------------------------------------------------------------
Floating Point Formatting
GS_DBL Copyright (c) Richard F. Griffin
16 February 1992
102 Molded Stone Pl
Warner Robins, GA 31088
-------------------------------------------------------------
This unit handles the routines to create and compare floating
point type doubles used in dBase indexes. These routines save
10K of memory over the $N,E option for numeric coprocessor emulation.
This unit will also convert from double to string. This is done
by first converting from double to real and then using the Str
procedure. Because of this, there may be inaccuracies for numbers
greater than 10-11 digits.
dBase III indexes use type double to store all numeric and date
field keys.
changes:
------------------------------------------------------------------------------}
unit GS_Dbl;
interface
{$D-}
type
{-----------------------------------------------------------------------------
gsDouble type simulates IEEE double precision type.
Memory layout is:
gsDouble Bytes
┌────────┬────────┬────────┬───┴────┬────────┬────────┬───────────┐
[7] [6] [5] [4] [3] [2] [1] [0]
76543210 76543210 76543210 76543210 76543210 76543210 76543210 76543210
seeeeeee│eeeemmmm│mmmmmmmm│mmmmmmmm│mmmmmmmm│mmmmmmmm│mmmmmmmm│mmmmmmmm
│└┴┴┴┴┴┴─┴┴┴┘└┴┴┴─┴┴┴┴┴┴┴┴─┴┴┴┴┴┴┴┴─┴┴┴┴┴┴┴┴─┴┴┴┴┴┴┴┴─┴┴┴┴┴┴┴┴─┴┴┴┴┴┴┴┘
│ Exponent Mantissa
└─ Sign
Note the value is stored opposite from its representation; that is, the
sign/(MSB exponent) byte is stored in gsDouble[7]. The next byte, with
the (LSB exponent)/ (MSB Mantissa) is gsDouble[6]; and so on.....
-----------------------------------------------------------------------------}
gsDouble = array[0..7] of byte;
function CmprDouble(var v1, v2) : integer;
procedure MakeDouble(C_String: string;var dtype: gsDouble;var rcode : integer);
function CnvrtDouble(var dtype) : string;
implementation
const
MaxNibble = 64;
MaxBcdNibble = 20;
EndNibble = 63;
var
Index : integer;
DecPlaces : integer;
TotPlaces : integer;
RndgFlag : boolean;
InDecimals : boolean;
InExponent : boolean;
PositiveNum : boolean;
PositiveExp : boolean;
Mantissa : array[0..MaxNibble] of byte;
Exponent : array[1..3] of byte;
DecExponent : integer;
BinExponent : longint;
GrtrZero : boolean;
DumpBit : byte;
rmdr,
LSp,
i : integer;
DblAry : array[1..16] of byte;
DblWrk : gsDouble;
function CmprDouble(var v1, v2) : integer;
var
val1 : gsDouble absolute v1;
val2 : gsDouble absolute v2;
val1neg,
val2neg : boolean;
flg : boolean;
rslt : integer;
loop : integer;
begin
val1neg := val1[7] > 127;
val2neg := val2[7] > 127;
flg := val1neg = val2neg;
if not flg then
begin
if val1neg then CmprDouble := -1 else CmprDouble := 1;
exit;
end;
loop := 7;
rslt := 0;
while (rslt = 0) and (loop >= 0) do
begin
if val1[loop] < val2[loop] then rslt := -1
else if val1[loop] > val2[loop] then rslt := 1;
loop:= loop-1;
end;
if val1neg then rslt := rslt*(-1);
CmprDouble := rslt;
end;
procedure MakeDouble(C_String: string;var dtype: gsDouble;var rcode : integer);
procedure AdjustMantissa;
begin
if DecExponent < 0 then
begin
while DecExponent < 0 do
begin
while Mantissa[1] = 0 do
begin
move(Mantissa[2], Mantissa[1], EndNibble);
dec(BinExponent,4);
end;
for i := 1 to pred(EndNibble) do
begin
Mantissa[succ(i)] := Mantissa[succ(i)] +
((Mantissa[i] mod 10) * 16);
Mantissa[i] := Mantissa[i] div 10;
end;
Mantissa[EndNibble] := Mantissa[EndNibble] div 10;
inc(DecExponent);
end;
end
else
{test for exponent > 0}
if DecExponent > 0 then
begin
while DecExponent > 0 do
begin
if Mantissa[1] <> 0 then
begin
rmdr := Mantissa[EndNibble];
move(Mantissa[1], Mantissa[2], pred(EndNibble));
Mantissa[1] := 0;
inc(BinExponent,4);
if rmdr > 7 then
begin
inc(Mantissa[EndNibble]);
i := EndNibble;
while Mantissa[i] > 15 do
begin
Mantissa[i] := Mantissa[i] and $0F;
dec(i);
inc(Mantissa[i]);
end;
end;
end;
Mantissa[EndNibble] := (Mantissa[EndNibble] * 10);
for i := pred(EndNibble) downto 1 do
begin
Mantissa[i] := (Mantissa[i] * 10) +
(Mantissa[succ(i)] shr 4);
Mantissa[succ(i)] :=
Mantissa[succ(i)] and $0F;
end;
dec(DecExponent);
end;
end;
end;
begin
rcode := 0;
PositiveNum := true;
PositiveExp := true;
DecPlaces := 0;
DecExponent := 0;
RndgFlag := true;
InDecimals := false;
InExponent := false;
FillChar(Mantissa,MaxNibble+1,#0);
FillChar(Exponent,3,#0);
if C_String <> '' then
begin
LSp := 1;
while (C_String[LSp] = ' ') and (LSp <= ord(C_String[0])) do
LSp := LSp+1;
for Index := LSp to length(C_String) do
begin
case C_String[Index] of
'+' : if InExponent then PositiveExp := true
else PositiveNum := true;
'-' : if InExponent then PositiveExp := false
else PositiveNum := false;
'0'..'9' : begin
if InDecimals then inc(DecPlaces);
if InExponent then
begin
DecExponent := (DecExponent * 10) +
byte(C_String[Index]) and $0F;
end
else
begin
if Mantissa[1] = 0 then
begin
Mantissa[EndNibble] :=
(Mantissa[EndNibble] * 10) +
(byte(C_String[Index]) and $0F);
for i := pred(EndNibble) downto 1 do
begin
Mantissa[i] := (Mantissa[i] * 10) +
(Mantissa[succ(i)] shr 4);
Mantissa[succ(i)] :=
Mantissa[succ(i)] and $0F;
end;
end
else
begin
if RndgFlag then
begin
RndgFlag := false;
if C_String[Index] > '4' then
inc(Mantissa[EndNibble]);
end;
if not InDecimals then dec(DecPlaces);
end;
end;
end;
'.' : InDecimals := true;
'e',
'E' : begin